<!--<template>
  <div class="pile-map-container">
    <div
        class="canvas-wrapper"
        @wheel="handleWheel"
        @mousedown="handleMouseDown"
        @mousemove="handleMouseMove"
        @mouseup="handleMouseUp"
        @mouseleave="handleMouseUp"
        @dblclick="handleDoubleClick"
        @touchstart="handleTouchStart"
        @touchmove="handleTouchMove"
        @touchend="handleTouchEnd"
    >
      <canvas ref="canvasRef" :width="canvasWidth" :height="canvasHeight"></canvas>
      <div v-if="debugMode" class="debug-info">
        <div>缩放: {{ view.scale.toFixed(2) }}</div>
        <div>平移: {{ view.offsetX.toFixed(2) }}, {{ view.offsetY.toFixed(2) }}</div>
        <div>桩点数量: {{ pileData.length }}</div>
        <div>桩点间距: {{ pileSpacing.toFixed(2) }}px</div>
        <div>文字大小: {{ getTextSize() }}px</div>
      </div>
    </div>
    <div class="pagination" :style="{ flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? '10px' : '16px' }">
      <button @click="prevPage" :class="{ disabled: currentPage === 1 }">
        上一页
      </button>
      <div class="page-info" v-show="!isMobile">
        第 {{ currentPage }} 页 / 共 {{ totalPages }} 页
      </div>
      <div class="page-info" v-show="isMobile">
        {{ currentPage }} / {{ totalPages }}
      </div>
      <button @click="nextPage" :class="{ disabled: currentPage === totalPages }">
        下一页
      </button>
      <button @click="toggleDebugMode">
        {{ debugMode ? '关闭调试' : '开启调试' }}
      </button>
      <button @click="resetView">
        重置视图
      </button>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, watch, reactive, computed, onUnmounted } from 'vue';
import { getPiles } from '@/apis/api_pile.js';
import { useRouter } from 'vue-router';

const canvasRef = ref(null);
const ctx = ref(null);
const pileData = ref([]);
const currentPage = ref(1);
const itemsPerPage = ref(492);
const totalPages = ref(1);
const statusColorMap = {
  未施工: '#00FFFF',
  施工中: '#FF0000',
  已完成: '#00FF00',
};

const isMobile = computed(() => /Mobile|Android|iOS/i.test(navigator.userAgent));

// 动态画布尺寸
const canvasWidth = ref(1500);
const canvasHeight = ref(1200);
const margin = { top: 10, right: 10, bottom: 10, left: 10 };

const view = reactive({
  scale: 1,
  offsetX: 0,
  offsetY: 0,
  isDragging: false,
  lastX: 0,
  lastY: 0,
  touchStartScale: 1,
  startX: 0,
  startY: 0,
  touchDistance: 0,
});

// 基础尺寸配置
const BASE_TEXT_SIZE = 16;
const MIN_PILE_SIZE = 4;
const MAX_PILE_SIZE = 20;
const BASE_PILE_SIZE = 15;
const SCALE_RATIO = 100;

// 桩点间距（用于自适应计算）
const pileSpacing = ref(0);

let lastClickTime = 0;
const DOUBLE_CLICK_DELAY = 300;
const router = useRouter();

// 调试模式
const debugMode = ref(false);
const mousePosition = ref({ x: 0, y: 0 });

// 坐标转换工具类
class CoordinateTransformer {
  constructor(canvas, view) {
    this.canvas = canvas;
    this.view = view;
  }

  // 从页面坐标转换为Canvas逻辑坐标
  pageToCanvas(pageX, pageY) {
    const rect = this.canvas.getBoundingClientRect();
    const clientX = pageX - rect.left;
    const clientY = pageY - rect.top;

    // 应用逆变换
    const worldX = (clientX - this.view.offsetX) / this.view.scale;
    const worldY = (clientY - this.view.offsetY) / this.view.scale;

    return { x: worldX, y: worldY };
  }

  // 从Canvas逻辑坐标转换为页面坐标
  canvasToPage(canvasX, canvasY) {
    const rect = this.canvas.getBoundingClientRect();
    const clientX = canvasX * this.view.scale + this.view.offsetX;
    const clientY = canvasY * this.view.scale + this.view.offsetY;

    return { x: clientX + rect.left, y: clientY + rect.top };
  }

  // 获取点击检测半径在页面上的实际像素大小
  getClickRadiusInPage() {
    return getAdjustedPileSize() * this.view.scale;
  }
}

// 创建坐标转换器实例
let transformer = null;

// 根据缩放级别获取调整后的桩点大小
function getAdjustedPileSize() {
  // 基础大小 + 随缩放变化的调整
  const size = BASE_PILE_SIZE / Math.sqrt(view.scale);
  return Math.max(MIN_PILE_SIZE, Math.min(MAX_PILE_SIZE, size));
}

// 根据桩点间距获取调整后的文字大小
function getTextSize() {
  // 基础文字大小，根据桩点间距调整
  const textSize = BASE_TEXT_SIZE * (pileSpacing.value / 50);
  return Math.max(8, Math.min(BASE_TEXT_SIZE, textSize));
}

function initCanvas() {
  if (!canvasRef.value) return;
  ctx.value = canvasRef.value.getContext('2d');
  transformer = new CoordinateTransformer(canvasRef.value, view);
  updateCanvasSize();
}

function updateCanvasSize() {
  if (isMobile.value) {
    canvasWidth.value = window.innerWidth;
    canvasHeight.value = window.innerHeight * 0.8;
  } else {
    canvasWidth.value = 1500;
    canvasHeight.value = 1200;
  }
}

// 触摸事件
function handleTouchStart(e) {
  if (e.touches.length === 1) {
    e.preventDefault();
    view.isDragging = true;
    view.lastX = e.touches[0].clientX;
    view.lastY = e.touches[0].clientY;
  } else if (e.touches.length === 2) {
    e.preventDefault();
    const touch1 = e.touches[0];
    const touch2 = e.touches[1];
    view.touchStartScale = view.scale;
    view.startX = (touch1.clientX + touch2.clientX) / 2;
    view.startY = (touch1.clientY + touch2.clientY) / 2;
    view.touchDistance = getDistance(touch1, touch2);
  }
}

function handleTouchMove(e) {
  if (e.touches.length === 1 && view.isDragging) {
    view.offsetX += e.touches[0].clientX - view.lastX;
    view.offsetY += e.touches[0].clientY - view.lastY;
    view.lastX = e.touches[0].clientX;
    view.lastY = e.touches[0].clientY;
    drawPiles();
  } else if (e.touches.length === 2) {
    e.preventDefault();
    const touch1 = e.touches[0];
    const touch2 = e.touches[1];
    const currentDistance = getDistance(touch1, touch2);
    const scaleFactor = currentDistance / view.touchDistance;

    const worldMouseX = (view.startX - view.offsetX) / view.touchStartScale;
    const worldMouseY = (view.startY - view.offsetY) / view.touchStartScale;

    view.scale = view.touchStartScale * scaleFactor;
    view.scale = Math.max(0.2, Math.min(500, view.scale));
    view.offsetX = view.startX - worldMouseX * view.scale;
    view.offsetY = view.startY - worldMouseY * view.scale;

    drawPiles();
  }
}

function handleTouchEnd() {
  view.isDragging = false;
}

function getDistance(touch1, touch2) {
  const dx = touch2.clientX - touch1.clientX;
  const dy = touch2.clientY - touch1.clientY;
  return Math.hypot(dx, dy);
}

// 原有事件
function handleWheel(e) {
  if (isMobile.value) return;
  e.preventDefault();

  const rect = canvasRef.value.getBoundingClientRect();
  const mouseX = e.clientX - rect.left;
  const mouseY = e.clientY - rect.top;

  const worldMouseX = (mouseX - view.offsetX) / view.scale;
  const worldMouseY = (mouseY - view.offsetY) / view.scale;

  view.scale *= e.deltaY > 0 ? 0.9 : 1.1;
  view.scale = Math.max(0.1, Math.min(1000, view.scale));
  view.offsetX = mouseX - worldMouseX * view.scale;
  view.offsetY = mouseY - worldMouseY * view.scale;

  drawPiles();
}

function handleMouseDown(e) {
  if (e.button !== 0 || isMobile.value) return;
  e.preventDefault();
  view.isDragging = true;
  view.lastX = e.clientX;
  view.lastY = e.clientY;
}

function handleMouseMove(e) {
  if (!view.isDragging || isMobile.value) return;
  view.offsetX += e.clientX - view.lastX;
  view.offsetY += e.clientY - view.lastY;
  view.lastX = e.clientX;
  view.lastY = e.clientY;
  drawPiles();

  // 更新鼠标位置（调试用）
  if (debugMode.value) {
    const rect = canvasRef.value.getBoundingClientRect();
    mousePosition.value = {
      x: e.clientX - rect.left,
      y: e.clientY - rect.top
    };
  }
}

function handleMouseUp() {
  view.isDragging = false;
}

function handleDoubleClick(e) {
  if (isMobile.value) e.preventDefault();

  // 使用坐标转换器
  const canvasPos = transformer.pageToCanvas(e.clientX, e.clientY);

  // 使用Canvas逻辑坐标查找桩点
  const clickedPile = findPileByCoordinate(canvasPos.x, canvasPos.y);

  if (clickedPile) {
    const targetUrl = `http://192.168.1.245:5173/pile/pileInfo/${clickedPile.pileNumber}`;
    window.location.href = targetUrl;
  }

  const now = Date.now();
  if (now - lastClickTime < DOUBLE_CLICK_DELAY && clickedPile) {
    lastClickTime = 0;
  } else {
    lastClickTime = now;
  }
}

// 直接使用逻辑坐标查找桩点
function findPileByCoordinate(worldX, worldY) {
  const pileSize = getAdjustedPileSize();
  return pileData.value.find(pile => {
    const dx = worldX - pile.coordinateX;
    const dy = worldY - pile.coordinateY;
    return Math.hypot(dx, dy) <= pileSize;
  });
}

// 切换调试模式
function toggleDebugMode() {
  debugMode.value = !debugMode.value;
  drawPiles();
}

// 重置视图
function resetView() {
  calculateViewParameters();
  drawPiles();
}

// 计算桩点间距（用于自适应布局）
function calculatePileSpacing() {
  if (!pileData.value.length) return 0;

  // 计算平均间距
  const xValues = pileData.value.map(p => p.coordinateX);
  const yValues = pileData.value.map(p => p.coordinateY);
  const xMin = Math.min(...xValues);
  const xMax = Math.max(...xValues);
  const yMin = Math.min(...yValues);
  const yMax = Math.max(...yValues);

  const width = xMax - xMin;
  const height = yMax - yMin;
  const area = width * height;
  const density = pileData.value.length / area;

  // 估算平均间距（平方根倒数）
  const spacing = 1 / Math.sqrt(density);
  pileSpacing.value = spacing;
  return spacing;
}

// 绘制函数
function drawAxis() {
  const { left, right, top, bottom } = margin;
  ctx.value.strokeStyle = '#333';
  ctx.value.lineWidth = 2;

  // X轴
  ctx.value.beginPath();
  ctx.value.moveTo(left, canvasHeight.value - bottom);
  ctx.value.lineTo(canvasWidth.value - right, canvasHeight.value - bottom);
  ctx.value.stroke();

  // Y轴
  ctx.value.beginPath();
  ctx.value.moveTo(left, top);
  ctx.value.lineTo(left, canvasHeight.value - bottom);
  ctx.value.stroke();

  // 标签
  const textSize = getTextSize();
  ctx.value.font = `${textSize}px Arial`;
  ctx.value.fillStyle = '#000';
  ctx.value.textAlign = 'center';
  ctx.value.fillText('X坐标 (米)', canvasWidth.value/2, canvasHeight.value - bottom + 25);

  ctx.value.save();
  ctx.value.translate(25, canvasHeight.value/2);
  ctx.value.rotate(-Math.PI/2);
  ctx.value.fillText('Y坐标 (米)', 0, 0);
  ctx.value.restore();

  ctx.value.font = `${textSize+2}px Arial`;
  ctx.value.fillText('桩基平面图', canvasWidth.value/2, 30);
}

function drawLegend() {
  const { left, top } = margin;
  const statusCount = Object.keys(statusColorMap).length;
  const itemHeight = 25;
  const padding = 15;

  const legendWidth = 120;
  const legendHeight = padding + 20 + statusCount * itemHeight;

  ctx.value.fillStyle = 'rgba(255,255,255,0.8)';
  ctx.value.fillRect(left+5, top+5, legendWidth, legendHeight);
  ctx.value.strokeRect(left+5, top+5, legendWidth, legendHeight);

  const textSize = getTextSize();
  ctx.value.font = `${textSize}px Arial`;
  ctx.value.fillStyle = '#000';
  ctx.value.fillText('图例', left+15, top+padding+10);

  Object.entries(statusColorMap).forEach(([status, color], index) => {
    const yPos = top + padding + 30 + index * itemHeight;
    ctx.value.beginPath();
    ctx.value.arc(left+20, yPos, 8, 0, Math.PI*2);
    ctx.value.fillStyle = color;
    ctx.value.fill();
    ctx.value.strokeStyle = '#333';
    ctx.value.stroke();
    ctx.value.font = `${textSize-2}px Arial`;
    ctx.value.fillText(status, left+35, yPos+3);
  });
}

function drawScaleBar() {
  const { left, bottom } = margin;
  const realWorldLength = 50;
  const scaledLength = (realWorldLength * view.scale) / SCALE_RATIO;

  ctx.value.beginPath();
  ctx.value.moveTo(left+20, canvasHeight.value - bottom - 20);
  ctx.value.lineTo(left+20+scaledLength, canvasHeight.value - bottom - 20);
  ctx.value.lineWidth = 2;
  ctx.value.stroke();

  ctx.value.beginPath();
  ctx.value.moveTo(left+20, canvasHeight.value - bottom - 15);
  ctx.value.lineTo(left+20, canvasHeight.value - bottom - 25);
  ctx.value.moveTo(left+20+scaledLength, canvasHeight.value - bottom - 15);
  ctx.value.lineTo(left+20+scaledLength, canvasHeight.value - bottom - 25);
  ctx.value.stroke();

  const textSize = getTextSize() - 2;
  ctx.value.font = `${textSize}px Arial`;
  ctx.value.fillText('0', left+20, canvasHeight.value - bottom - 5);
  ctx.value.fillText(`${realWorldLength}m`, left+20+scaledLength, canvasHeight.value - bottom - 5);
  ctx.value.fillText(`1:${SCALE_RATIO}`, left+20, canvasHeight.value - bottom - 30);
}

function drawGrid(xMin, xMax, yMin, yMax) {
  ctx.value.strokeStyle = '#f0f0f0';
  const gridSize = 50;

  for (let x = Math.floor(xMin/gridSize)*gridSize; x < xMax; x += gridSize) {
    ctx.value.beginPath();
    ctx.value.moveTo(x, yMin);
    ctx.value.lineTo(x, yMax);
    ctx.value.stroke();
  }

  for (let y = Math.floor(yMin/gridSize)*gridSize; y < yMax; y += gridSize) {
    ctx.value.beginPath();
    ctx.value.moveTo(xMin, y);
    ctx.value.lineTo(xMax, y);
    ctx.value.stroke();
  }
}

function drawPiles() {
  if (!ctx.value || !pileData.value.length) return;

  const xValues = pileData.value.map(p => p.coordinateX);
  const yValues = pileData.value.map(p => p.coordinateY);
  const xMin = Math.min(...xValues);
  const xMax = Math.max(...xValues);
  const yMin = Math.min(...yValues);
  const yMax = Math.max(...yValues);

  ctx.value.clearRect(0, 0, canvasWidth.value, canvasHeight.value);
  ctx.value.save();

  // 应用变换
  ctx.value.translate(view.offsetX, view.offsetY);
  ctx.value.scale(view.scale, view.scale);

  drawGrid(xMin, xMax, yMin, yMax);
  drawAxis();

  const pileSize = getAdjustedPileSize();
  const textSize = getTextSize();

  pileData.value.forEach(pile => {
    const status = getStatus(pile);
    const color = statusColorMap[status];
    const x = pile.coordinateX;
    const y = pile.coordinateY;

    // 绘制桩点
    ctx.value.beginPath();
    ctx.value.arc(x, y, pileSize, 0, Math.PI*2);
    ctx.value.fillStyle = color;
    ctx.value.fill();
    ctx.value.strokeStyle = '#333';
    ctx.value.stroke();

    // 绘制桩号
    ctx.value.font = `${textSize}px Arial`;
    ctx.value.fillStyle = '#333';
    ctx.value.textAlign = 'center';
    ctx.value.textBaseline = 'middle';
    ctx.value.fillText(pile.pileNumber, x, y);

    // 调试模式下显示点击区域
    if (debugMode.value) {
      ctx.value.beginPath();
      ctx.value.arc(x, y, pileSize, 0, Math.PI*2);
      ctx.value.strokeStyle = 'rgba(255, 0, 0, 0.5)';
      ctx.value.lineWidth = 2;
      ctx.value.stroke();
    }
  });

  ctx.value.restore();
  drawLegend();
  drawScaleBar();

  // 调试模式下显示鼠标位置
  if (debugMode.value && mousePosition.value.x > 0) {
    const canvasPos = transformer.pageToCanvas(
        mousePosition.value.x + canvasRef.value.getBoundingClientRect().left,
        mousePosition.value.y + canvasRef.value.getBoundingClientRect().top
    );

    ctx.value.save();
    ctx.value.beginPath();
    ctx.value.arc(
        canvasPos.x * view.scale + view.offsetX,
        canvasPos.y * view.scale + view.offsetY,
        5, 0, Math.PI*2
    );
    ctx.value.fillStyle = 'rgba(0, 0, 255, 0.7)';
    ctx.value.fill();
    ctx.value.restore();
  }
}

function getStatus(item) {
  if (!item.holeOpeningTime) return '未施工';
  if (!item.pouringTime) return '施工中';
  return '已完成';
}

function calculateViewParameters() {
  if (!pileData.value.length) return;

  // 计算桩点间距
  calculatePileSpacing();

  const xValues = pileData.value.map(p => p.coordinateX);
  const yValues = pileData.value.map(p => p.coordinateY);
  const xMin = Math.min(...xValues);
  const xMax = Math.max(...xValues);
  const yMin = Math.min(...yValues);
  const yMax = Math.max(...yValues);

  const contentWidth = xMax - xMin;
  const contentHeight = yMax - yMin;
  const plotWidth = canvasWidth.value - margin.left - margin.right;
  const plotHeight = canvasHeight.value - margin.top - margin.bottom;

  if (contentWidth === 0 || contentHeight === 0) return;

  // 计算缩放比例，考虑桩点间距和文字大小
  const baseScaleX = plotWidth / contentWidth * 0.8;
  const baseScaleY = plotHeight / contentHeight * 0.8;

  // 根据桩点密度调整缩放
  const densityFactor = Math.min(1, 50 / pileSpacing.value); // 密度越大，缩放越小
  const adjustedScaleX = baseScaleX * densityFactor;
  const adjustedScaleY = baseScaleY * densityFactor;

  view.scale = Math.min(adjustedScaleX, adjustedScaleY);

  const centerX = (xMin + xMax) / 2;
  const centerY = (yMin + yMax) / 2;
  view.offsetX = (canvasWidth.value - margin.left - margin.right) / 2 - centerX * view.scale;
  view.offsetY = (canvasHeight.value - margin.top - margin.bottom) / 2 - centerY * view.scale;
}

async function loadData(page = 1) {
  currentPage.value = page;
  try {
    const res = await getPiles(page, itemsPerPage.value);
    pileData.value = res.records || [];
    totalPages.value = res.pages || 1;
    calculateViewParameters();
    drawPiles();
  } catch (error) {
    console.error('数据加载失败:', error);
  }
}

watch(pileData, () => {
  calculateViewParameters();
  drawPiles();
}, { deep: true });

function prevPage() {
  if (currentPage.value > 1) loadData(currentPage.value - 1);
}

function nextPage() {
  if (currentPage.value < totalPages.value) loadData(currentPage.value + 1);
}

watch(() => [window.innerWidth, window.innerHeight], () => {
  if (canvasRef.value) {
    updateCanvasSize();
    calculateViewParameters();
    drawPiles();
  }
}, { immediate: true });

onMounted(() => {
  initCanvas();
  loadData();
});

onUnmounted(() => {
  transformer = null;
});
</script>-->

<template>
  <div class="pile-map-container">
    <div
        class="canvas-wrapper"
        @wheel="handleWheel"
        @mousedown="handleMouseDown"
        @mousemove="handleMouseMove"
        @mouseup="handleMouseUp"
        @mouseleave="handleMouseUp"
        @dblclick="handleDoubleClick"
        @touchstart="handleTouchStart"
        @touchmove="handleTouchMove"
        @touchend="handleTouchEnd"
    >
      <canvas ref="canvasRef" :width="canvasWidth" :height="canvasHeight"></canvas>
      <div v-if="debugMode" class="debug-info">
        <div>缩放: {{ view.scale.toFixed(2) }}</div>
        <div>平移: {{ view.offsetX.toFixed(2) }}, {{ view.offsetY.toFixed(2) }}</div>
        <div>世界单位/像素: {{ worldUnitsPerPixel.toFixed(2) }}</div>
      </div>
    </div>
    <div class="pagination" :style="{ flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? '10px' : '16px' }">
      <button @click="prevPage" :class="{ disabled: currentPage === 1 }">
        上一页
      </button>
      <div class="page-info" v-show="!isMobile">
        第 {{ currentPage }} 页 / 共 {{ totalPages }} 页
      </div>
      <div class="page-info" v-show="isMobile">
        {{ currentPage }} / {{ totalPages }}
      </div>
      <button @click="nextPage" :class="{ disabled: currentPage === totalPages }">
        下一页
      </button>
      <button @click="toggleDebugMode">
        {{ debugMode ? '关闭调试' : '开启调试' }}
      </button>
      <button @click="resetView">
        重置视图
      </button>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, watch, reactive, computed, onUnmounted } from 'vue';
import { getPiles } from '@/apis/api_pile.js';
//import { useRouter } from 'vue-router';
import router from "@/router/index.js";
const canvasRef = ref(null);
const ctx = ref(null);
const pileData = ref([]);
const currentPage = ref(1);
const itemsPerPage = ref(492);
const totalPages = ref(1);
const statusColorMap = {
  未施工: '#00FFFF',
  施工中: '#FF0000',
  已完成: '#00FF00',
};

const isMobile = computed(() => /Mobile|Android|iOS/i.test(navigator.userAgent));

// 动态画布尺寸
const canvasWidth = ref(1500);
const canvasHeight = ref(1200);
const margin = { top: 10, right: 10, bottom: 10, left: 10 };

const view = reactive({
  scale: 1,         // 世界坐标系到屏幕坐标系的缩放比例
  offsetX: 0,
  offsetY: 0,
  isDragging: false,
  lastX: 0,
  lastY: 0,
  touchStartScale: 1,
  startX: 0,
  startY: 0,
  touchDistance: 0,
});

// 固定尺寸配置（世界单位）
const FIXED_PILE_SIZE = 0.75;   // 桩点固定大小（米）
const FIXED_TEXT_SIZE = 0.5;   // 文字固定大小（米）
const MIN_VISIBLE_SCALE = 0.1; // 最小可见缩放比例
const MAX_VISIBLE_SCALE = 1000; // 最大可见缩放比例
const SCALE_RATIO = 100;

// 世界单位到像素的转换比例
const worldUnitsPerPixel = computed(() => 1 / view.scale);

let lastClickTime = 0;
const DOUBLE_CLICK_DELAY = 300;


// 调试模式
const debugMode = ref(false);
const mousePosition = ref({ x: 0, y: 0 });

// 坐标转换工具类
class CoordinateTransformer {
  constructor(canvas, view) {
    this.canvas = canvas;
    this.view = view;
  }

  // 从世界坐标转换为屏幕坐标
  worldToScreen(worldX, worldY) {
    const screenX = worldX * this.view.scale + this.view.offsetX;
    const screenY = worldY * this.view.scale + this.view.offsetY;
    return { x: screenX, y: screenY };
  }

  // 从屏幕坐标转换为世界坐标
  screenToWorld(screenX, screenY) {
    const worldX = (screenX - this.view.offsetX) / this.view.scale;
    const worldY = (screenY - this.view.offsetY) / this.view.scale;
    return { x: worldX, y: worldY };
  }

  // 获取点击检测半径（世界单位）
  getClickRadius() {
    return FIXED_PILE_SIZE;
  }
}

// 创建坐标转换器实例
let transformer = null;

function initCanvas() {
  if (!canvasRef.value) return;
  ctx.value = canvasRef.value.getContext('2d');
  transformer = new CoordinateTransformer(canvasRef.value, view);
  updateCanvasSize();
}

function updateCanvasSize() {
  if (isMobile.value) {
    canvasWidth.value = window.innerWidth;
    canvasHeight.value = window.innerHeight * 0.8;
  } else {
    canvasWidth.value = 1500;
    canvasHeight.value = 1200;
  }
}

// 触摸事件
function handleTouchStart(e) {
  if (e.touches.length === 1) {
    e.preventDefault();
    view.isDragging = true;
    view.lastX = e.touches[0].clientX;
    view.lastY = e.touches[0].clientY;
  } else if (e.touches.length === 2) {
    e.preventDefault();
    const touch1 = e.touches[0];
    const touch2 = e.touches[1];
    view.touchStartScale = view.scale;
    view.startX = (touch1.clientX + touch2.clientX) / 2;
    view.startY = (touch1.clientY + touch2.clientY) / 2;
    view.touchDistance = getDistance(touch1, touch2);
  }
}

function handleTouchMove(e) {
  if (e.touches.length === 1 && view.isDragging) {
    view.offsetX += e.touches[0].clientX - view.lastX;
    view.offsetY += e.touches[0].clientY - view.lastY;
    view.lastX = e.touches[0].clientX;
    view.lastY = e.touches[0].clientY;
    drawPiles();
  } else if (e.touches.length === 2) {
    e.preventDefault();
    const touch1 = e.touches[0];
    const touch2 = e.touches[1];
    const currentDistance = getDistance(touch1, touch2);
    const scaleFactor = currentDistance / view.touchDistance;

    const worldMouseX = (view.startX - view.offsetX) / view.touchStartScale;
    const worldMouseY = (view.startY - view.offsetY) / view.touchStartScale;

    view.scale = view.touchStartScale * scaleFactor;
    view.scale = Math.max(MIN_VISIBLE_SCALE, Math.min(MAX_VISIBLE_SCALE, view.scale));
    view.offsetX = view.startX - worldMouseX * view.scale;
    view.offsetY = view.startY - worldMouseY * view.scale;

    drawPiles();
  }
}

function handleTouchEnd() {
  view.isDragging = false;
}

function getDistance(touch1, touch2) {
  const dx = touch2.clientX - touch1.clientX;
  const dy = touch2.clientY - touch1.clientY;
  return Math.hypot(dx, dy);
}

// 原有事件
function handleWheel(e) {
  if (isMobile.value) return;
  e.preventDefault();

  const rect = canvasRef.value.getBoundingClientRect();
  const screenX = e.clientX - rect.left;
  const screenY = e.clientY - rect.top;

  const worldMouse = transformer.screenToWorld(screenX, screenY);

  // 缩放时保持鼠标位置对应的世界坐标不变
  view.scale *= e.deltaY > 0 ? 0.9 : 1.1;
  view.scale = Math.max(MIN_VISIBLE_SCALE, Math.min(MAX_VISIBLE_SCALE, view.scale));

  // 重新计算偏移量，保持鼠标位置对应的世界坐标不变
  view.offsetX = screenX - worldMouse.x * view.scale;
  view.offsetY = screenY - worldMouse.y * view.scale;

  drawPiles();
}

function handleMouseDown(e) {
  if (e.button !== 0 || isMobile.value) return;
  e.preventDefault();
  view.isDragging = true;
  view.lastX = e.clientX;
  view.lastY = e.clientY;
}

function handleMouseMove(e) {
  if (!view.isDragging || isMobile.value) return;
  view.offsetX += e.clientX - view.lastX;
  view.offsetY += e.clientY - view.lastY;
  view.lastX = e.clientX;
  view.lastY = e.clientY;
  drawPiles();

  // 更新鼠标位置（调试用）
  if (debugMode.value) {
    const rect = canvasRef.value.getBoundingClientRect();
    mousePosition.value = {
      x: e.clientX - rect.left,
      y: e.clientY - rect.top
    };
  }
}

function handleMouseUp() {
  view.isDragging = false;
}

function handleDoubleClick(e) {
  if (isMobile.value) e.preventDefault();

  const rect = canvasRef.value.getBoundingClientRect();
  const screenX = e.clientX - rect.left;
  const screenY = e.clientY - rect.top;

  // 使用坐标转换器
  const worldPos = transformer.screenToWorld(screenX, screenY);

  // 使用世界坐标查找桩点
  const clickedPile = findPileByCoordinate(worldPos.x, worldPos.y);

  if (clickedPile) {
   /* const targetUrl = `/pile/pileInfo/${clickedPile.pileNumber}`;
    //const targetUrl = `http://192.168.1.245:5173/pile/pileInfo/${clickedPile.pileNumber}`;
    window.location.href = targetUrl;*/

    router.push(`/pile/pileInfo/${clickedPile.pileNumber}`);
  }

  const now = Date.now();
  if (now - lastClickTime < DOUBLE_CLICK_DELAY && clickedPile) {
    lastClickTime = 0;
  } else {
    lastClickTime = now;
  }
}

// 使用世界坐标查找桩点
function findPileByCoordinate(worldX, worldY) {
  return pileData.value.find(pile => {
    const dx = worldX - pile.coordinateX;
    const dy = worldY - pile.coordinateY;
    return Math.hypot(dx, dy) <= FIXED_PILE_SIZE;
  });
}

// 切换调试模式
function toggleDebugMode() {
  debugMode.value = !debugMode.value;
  drawPiles();
}

// 重置视图
function resetView() {
  calculateViewParameters();
  drawPiles();
}

// 绘制函数
function drawAxis() {
  const { left, right, top, bottom } = margin;

  // 绘制坐标轴（使用世界坐标系）
  ctx.value.strokeStyle = '#333';
  ctx.value.lineWidth = 1;

  // X轴
  const xAxisY = canvasHeight.value - bottom;
  ctx.value.beginPath();
  ctx.value.moveTo(left, xAxisY);
  ctx.value.lineTo(canvasWidth.value - right, xAxisY);
  ctx.value.stroke();

  // Y轴
  const yAxisX = left;
  ctx.value.beginPath();
  ctx.value.moveTo(yAxisX, top);
  ctx.value.lineTo(yAxisX, canvasHeight.value - bottom);
  ctx.value.stroke();

  // 绘制坐标刻度
  drawAxisTicks();

  // 标签
  ctx.value.font = '16px Arial';
  ctx.value.fillStyle = '#000';
  ctx.value.textAlign = 'center';
  ctx.value.fillText('X坐标 (米)', canvasWidth.value/2, xAxisY + 25);

  ctx.value.save();
  ctx.value.translate(25, canvasHeight.value/2);
  ctx.value.rotate(-Math.PI/2);
  ctx.value.fillText('Y坐标 (米)', 0, 0);
  ctx.value.restore();

  ctx.value.font = '24px Arial';
  ctx.value.fillText('桩基平面图', canvasWidth.value/2, 30);
}

function drawAxisTicks() {
  const { left, right, top, bottom } = margin;
  const xAxisY = canvasHeight.value - bottom;
  const yAxisX = left;

  // 计算刻度间隔（世界单位）
  const tickSpacingWorld = getTickSpacing();

  // 计算可见区域的世界坐标范围
  const visibleWorldLeft = (left - view.offsetX) / view.scale;
  const visibleWorldRight = (canvasWidth.value - right - view.offsetX) / view.scale;
  const visibleWorldTop = (top - view.offsetY) / view.scale;
  const visibleWorldBottom = (canvasHeight.value - bottom - view.offsetY) / view.scale;

  // 绘制X轴刻度
  const firstXTick = Math.ceil(visibleWorldLeft / tickSpacingWorld) * tickSpacingWorld;
  for (let worldX = firstXTick; worldX < visibleWorldRight; worldX += tickSpacingWorld) {
    const screenX = worldX * view.scale + view.offsetX;

    ctx.value.beginPath();
    ctx.value.moveTo(screenX, xAxisY - 5);
    ctx.value.lineTo(screenX, xAxisY + 5);
    ctx.value.stroke();

    ctx.value.font = '12px Arial';
    ctx.value.textAlign = 'center';
    ctx.value.textBaseline = 'top';
    ctx.value.fillText(worldX.toFixed(0), screenX, xAxisY + 5);
  }

  // 绘制Y轴刻度
  const firstYTick = Math.ceil(visibleWorldBottom / tickSpacingWorld) * tickSpacingWorld;
  for (let worldY = firstYTick; worldY > visibleWorldTop; worldY -= tickSpacingWorld) {
    const screenY = worldY * view.scale + view.offsetY;

    ctx.value.beginPath();
    ctx.value.moveTo(yAxisX - 5, screenY);
    ctx.value.lineTo(yAxisX + 5, screenY);
    ctx.value.stroke();

    ctx.value.font = '12px Arial';
    ctx.value.textAlign = 'right';
    ctx.value.textBaseline = 'middle';
    ctx.value.fillText(worldY.toFixed(0), yAxisX - 5, screenY);
  }
}

// 计算合适的刻度间隔
function getTickSpacing() {
  // 根据当前缩放级别动态调整刻度间隔
  const scale = view.scale;
  if (scale >= 10) return 1;
  if (scale >= 5) return 5;
  if (scale >= 1) return 10;
  if (scale >= 0.5) return 50;
  if (scale >= 0.1) return 100;
  return 500;
}

function drawLegend() {
  const { left, top } = margin;

  const statusCount = Object.keys(statusColorMap).length;
  const itemHeight = 25;
  const padding = 15;

  const legendWidth = 140;
  const legendHeight = padding + 20 + statusCount * itemHeight;

  ctx.value.fillStyle = 'rgba(255,255,255,0.1)';
  ctx.value.fillRect(left+5, top+5, legendWidth, legendHeight);
  ctx.value.strokeRect(left+5, top+5, legendWidth, legendHeight);

  ctx.value.font = '22px Arial';
  ctx.value.fillStyle = '#000';
  ctx.value.fillText('图例', left+30, top+padding+10);

  Object.entries(statusColorMap).forEach(([status, color], index) => {
    const yPos = top + padding + 20 + index * itemHeight;
    ctx.value.beginPath();
    ctx.value.arc(left+20, yPos+12, 10, 0, Math.PI*2);
    ctx.value.fillStyle = color;
    ctx.value.fill();
    ctx.value.strokeStyle = '#333';
    ctx.value.stroke();
    ctx.value.font = '20px 宋体';
    console.log(index,count0);
    if(index===0){
      ctx.value.fillText(status+count0.value, left+82, yPos+12);
    }else if(index===1){
      ctx.value.fillText(status+count1.value, left+75, yPos+12);
    }else if(index===2){
      ctx.value.fillText(status+count2.value, left+80, yPos+12);
    }

  });
}

function drawScaleBar() {
  const { left, bottom } = margin;
  const realWorldLength = 50;
  const screenLength = realWorldLength * view.scale;

  ctx.value.beginPath();
  ctx.value.moveTo(left+20, canvasHeight.value - bottom - 20);
  ctx.value.lineTo(left+20+screenLength, canvasHeight.value - bottom - 20);
  ctx.value.lineWidth = 2;
  ctx.value.stroke();

  ctx.value.beginPath();
  ctx.value.moveTo(left+20, canvasHeight.value - bottom - 15);
  ctx.value.lineTo(left+20, canvasHeight.value - bottom - 25);
  ctx.value.moveTo(left+20+screenLength, canvasHeight.value - bottom - 15);
  ctx.value.lineTo(left+20+screenLength, canvasHeight.value - bottom - 25);
  ctx.value.stroke();

  ctx.value.font = '12px Arial';
  ctx.value.fillText('0', left+20, canvasHeight.value - bottom - 5);
  ctx.value.fillText(`${realWorldLength}m`, left+20+screenLength, canvasHeight.value - bottom - 5);
  ctx.value.fillText(`1:${Math.round(1/view.scale)}`, left+20, canvasHeight.value - bottom - 30);
}

function drawGrid() {
  const { left, right, top, bottom } = margin;

  // 计算网格间隔（世界单位）
  const gridSpacingWorld = getGridSpacing();

  // 计算可见区域的世界坐标范围
  const visibleWorldLeft = (left - view.offsetX) / view.scale;
  const visibleWorldRight = (canvasWidth.value - right - view.offsetX) / view.scale;
  const visibleWorldTop = (top - view.offsetY) / view.scale;
  const visibleWorldBottom = (canvasHeight.value - bottom - view.offsetY) / view.scale;

  // 绘制网格
  ctx.value.strokeStyle = '#f0f0f0';
  ctx.value.lineWidth = 1;

  // 垂直网格线
  const firstXGrid = Math.floor(visibleWorldLeft / gridSpacingWorld) * gridSpacingWorld;
  for (let worldX = firstXGrid; worldX <= visibleWorldRight; worldX += gridSpacingWorld) {
    const screenX = worldX * view.scale + view.offsetX;

    ctx.value.beginPath();
    ctx.value.moveTo(screenX, top);
    ctx.value.lineTo(screenX, canvasHeight.value - bottom);
    ctx.value.stroke();
  }

  // 水平网格线
  const firstYGrid = Math.floor(visibleWorldTop / gridSpacingWorld) * gridSpacingWorld;
  for (let worldY = firstYGrid; worldY <= visibleWorldBottom; worldY += gridSpacingWorld) {
    const screenY = worldY * view.scale + view.offsetY;

    ctx.value.beginPath();
    ctx.value.moveTo(left, screenY);
    ctx.value.lineTo(canvasWidth.value - right, screenY);
    ctx.value.stroke();
  }
}

// 计算合适的网格间隔
function getGridSpacing() {
  // 根据当前缩放级别动态调整网格间隔
  const scale = view.scale;
  if (scale >= 10) return 10;
  if (scale >= 5) return 50;
  if (scale >= 1) return 100;
  if (scale >= 0.5) return 500;
  if (scale >= 0.1) return 1000;
  return 5000;
}

const count0=ref(0)
const count1=ref(0)
const count2=ref(0)

function drawPiles() {

  count0.value=0
  count1.value=0
  count2.value=0

  if (!ctx.value || !pileData.value.length) return;

  ctx.value.clearRect(0, 0, canvasWidth.value, canvasHeight.value);

  // 绘制网格和坐标轴
  drawGrid();
  drawAxis();

  // 绘制所有桩点
  pileData.value.forEach(pile => {
    const status = getStatus(pile);
    // console.log(status==='未施工' )
    switch (status) {
        case '未施工':
          count0.value=count0.value+1;
          //console.log(count0.value+status)
          break
        case '施工中':
          count1.value=count1.value+1;
         // console.log(count0.value+status)
          break
        case '已完成':
          count2.value=count2.value+1;
         // console.log(count0.value+status)
          break
    }
   // console.log(count0.value,count1.value,count2.value)
    const color = statusColorMap[status];
    const worldX = pile.coordinateX;
    const worldY = pile.coordinateY;

    // 转换为屏幕坐标
    const screenPos = transformer.worldToScreen(worldX, worldY);

    // 绘制固定大小的桩点（屏幕坐标）
    ctx.value.beginPath();
    ctx.value.arc(screenPos.x, screenPos.y, FIXED_PILE_SIZE * view.scale, 0, Math.PI*2);
    ctx.value.fillStyle = color;
    ctx.value.fill();
    ctx.value.strokeStyle = '#333';
    ctx.value.stroke();

    // 绘制固定大小的文字（屏幕坐标）
    const textSize = Math.max(8, FIXED_TEXT_SIZE * view.scale);
    ctx.value.font = `${textSize}px Arial`;
    ctx.value.fillStyle = '#333';
    ctx.value.textAlign = 'center';
    ctx.value.textBaseline = 'middle';
    ctx.value.fillText(pile.pileNumber, screenPos.x, screenPos.y);
  });

  // 绘制图例和比例尺（固定在屏幕上）
  drawLegend();
  drawScaleBar();

  // 调试模式下显示鼠标位置
  if (debugMode.value && mousePosition.value.x > 0) {
    const worldPos = transformer.screenToWorld(
        mousePosition.value.x,
        mousePosition.value.y
    );

    ctx.value.save();
    ctx.value.beginPath();
    ctx.value.arc(
        mousePosition.value.x,
        mousePosition.value.y,
        5, 0, Math.PI*2
    );
    ctx.value.fillStyle = 'rgba(0, 0, 255, 0.7)';
    ctx.value.fill();

    // 显示鼠标位置的世界坐标
    ctx.value.font = '12px Arial';
    ctx.value.fillStyle = '#000';
    ctx.value.fillText(
        `(${worldPos.x.toFixed(2)}, ${worldPos.y.toFixed(2)})`,
        mousePosition.value.x + 10,
        mousePosition.value.y - 10
    );
    ctx.value.restore();
  }
}

function getStatus(item) {
  if (!item.holeOpeningTime) return '未施工';
  if (!item.pouringTime) return '施工中';
  return '已完成';
}

function calculateViewParameters() {
  if (!pileData.value.length) return;

  const xValues = pileData.value.map(p => p.coordinateX);
  const yValues = pileData.value.map(p => p.coordinateY);
  const xMin = Math.min(...xValues);
  const xMax = Math.max(...xValues);
  const yMin = Math.min(...yValues);
  const yMax = Math.max(...yValues);

  const contentWidth = xMax - xMin;
  const contentHeight = yMax - yMin;
  const plotWidth = canvasWidth.value - margin.left - margin.right;
  const plotHeight = canvasHeight.value - margin.top - margin.bottom;

  if (contentWidth === 0 || contentHeight === 0) return;

  // 计算能容纳所有桩点的缩放比例
  const scaleX = plotWidth / contentWidth * 0.8;
  const scaleY = plotHeight / contentHeight * 0.8;
  view.scale = Math.max(MIN_VISIBLE_SCALE, Math.min(scaleX, scaleY));

  const centerX = (xMin + xMax) / 2;
  const centerY = (yMin + yMax) / 2;
  view.offsetX = plotWidth / 2 - centerX * view.scale;
  view.offsetY = plotHeight / 2 - centerY * view.scale;
}

async function loadData(page = 1) {
  currentPage.value = page;
  try {
    const res = await getPiles(page, itemsPerPage.value);
    console.log("bulkheadindex loadData=>",res)
    pileData.value = res.data.records || [];
    totalPages.value = res.data.pages || 1;
    calculateViewParameters();
    drawPiles();
  } catch (error) {
    console.error('数据加载失败:', error);
  }
}

watch(pileData, () => {
  calculateViewParameters();
  drawPiles();
}, { deep: true });

function prevPage() {
  if (currentPage.value > 1) loadData(currentPage.value - 1);
}

function nextPage() {
  if (currentPage.value < totalPages.value) loadData(currentPage.value + 1);
}

watch(() => [window.innerWidth, window.innerHeight], () => {
  if (canvasRef.value) {
    updateCanvasSize();
    calculateViewParameters();
    drawPiles();
  }
}, { immediate: true });

onMounted(() => {
  initCanvas();
  loadData();
});

onUnmounted(() => {
  transformer = null;
});
</script>

<style lang="scss">
.pile-map-container {
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  padding: 10px;
  background-color: #f5f5f5;
}

.canvas-wrapper {
  flex: 1;
  position: relative;
  background: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  overflow: hidden;
  cursor: grab;
}

canvas {
  display: block;
  width: 100%!important;
  height: 100%!important;
  image-rendering: optimizeSpeed;
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 15px 0;
  gap: 10px;
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  margin-top: 15px;
}

button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
  display: flex;
  align-items: center;
  gap: 4px;
  background-color: #409eff;
  color: white;
}

button:hover:not(.disabled) {
  background-color: #66b1ff;
}

button.disabled {
  background-color: #f5f5f5;
  color: #999;
  cursor: not-allowed;
}

.page-info {
  font-size: 14px;
  color: #666;
}

/* 移动端优化 */
@media (max-width: 768px) {
  .canvas-wrapper {
    height: calc(100vh - 120px);
  }

  .pagination {
    flex-direction: row;
    justify-content: space-around;
    padding: 15px;
  }

  .page-info {
    display: block!important;
    margin: 0 10px;
  }

  button {
    padding: 6px 12px;
    font-size: 13px;
  }
}

/* 拖动样式 */
.canvas-wrapper.dragging {
  cursor: grabbing;
}

.canvas-wrapper.dragging::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* 调试信息样式 */
.debug-info {
  position: absolute;
  top: 10px;
  right: 10px;
  background-color: rgba(255, 255, 255, 0.8);
  padding: 8px;
  border-radius: 4px;
  font-size: 12px;
  z-index: 10;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
</style>
<!--
<style scoped lang="scss">
.pile-map-container {
  width: 100%;
  padding: 20px;
  box-sizing: border-box;
  background-color: #000; // 容器背景黑色
}

.canvas-wrapper {
  width: 100%;
  height: 800px;
  position: relative;
  background: #000; // 画布容器黑色背景
  border: 1px solid #333; // 深灰色边框
  border-radius: 4px;
  overflow: hidden;
  cursor: move;
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
}

.pagination {
  margin: 20px 0;
  text-align: center;
  color: #fff; // 分页文字白色
}

button {
  padding: 8px 16px;
  margin: 0 4px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  background-color: #409eff; // 按钮颜色保持蓝色
  color: white;
  transition: background-color 0.3s;
}

button:hover:not(.disabled) {
  background-color: #66b1ff;
}

button.disabled {
  background-color: #555; // 禁用按钮深灰色
  color: #999;
  cursor: not-allowed;
}

/* 以下为新增或修改的视觉元素样式 */

// 坐标轴颜色改为白色
.draw-axis line, .draw-axis path {
  stroke: #fff;
}

// 网格线改为深灰色
.grid-line {
  stroke: #333;
}

// 桩基状态颜色调整（提高在黑色背景的对比度）
.status-unconstructed { fill: #444; } // 未施工：深灰
.status-constructing { fill: #ffd700; } // 施工中：金色
.status-completed { fill: #0f0; } // 已完成：绿色

// 比例尺和图例文字改为白色
.scale-text, .legend-text {
  fill: #fff;
}

// 选中桩基的高亮边框改为红色
.selected-pile {
  stroke: #f00;
  stroke-width: 3px;
}
</style>-->
